<template>
  <div>
    <div
      class="excute-button-group"
      style="padding: 10px 10px 0;margin-bottom: 55px"
    >
      <el-button
        v-if="sqlExecuting"
        primary
        :disabled="paneClickDisable"
        v-on:click="cancelExecutorSql"
        type="primary"
        plain
        size="small"
        icon="el-icon-video-pause"
        >取消执行</el-button
      >
      <el-tooltip
        v-else
        effect="dark"
        content="Ctrl+R、Ctrl+Enter"
        placement="top"
      >
        <el-button
          v-on:click="doExecutorSql"
          size="small"
          type="primary"
          :disabled="paneClickDisable"
          icon="el-icon-video-play"
          >执行</el-button
        >
      </el-tooltip>
      <el-button
        icon="el-icon-brush"
        type="primary"
        size="small"
        :disabled="paneClickDisable"
        @click="formatterSql"
        >SQL美化</el-button
      >
      <el-button
        v-on:click="loadHistoryAndFavoriteList"
        size="small"
        type="primary"
        icon="el-icon-star-off"
        >保存历史</el-button
      >
      <el-dropdown style="margin-left: 10px" @command="handleCommand">
        <el-button size="small" type="primary">
          <i class="el-icon-arrow-down el-icon--right el-icon-download"></i
          >查询结果导出
        </el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="all-select">导出CSV</el-dropdown-item>
          <el-dropdown-item command="all-excel">导出Excel</el-dropdown-item>
          <el-dropdown-item command="select-excel"
            >导出选中Excel</el-dropdown-item
          >
          <el-dropdown-item command="select-csv">导出选中CSV</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>

      <el-button
        v-if="paneShow"
        v-on:click="changePane"
        :disabled="paneClickDisable"
        size="small"
        type="primary"
        style="margin-left: 10px"
        icon="el-icon-remove-outline"
        >收起标签页</el-button
      >
      <el-button
        v-if="!paneShow"
        v-on:click="changePane"
        size="small"
        type="primary"
        style="margin-left: 10px"
        icon="el-icon-circle-plus-outline"
        >打开标签页</el-button
      >
    </div>

    <Editor></Editor>

    <el-drawer
      title="保存及历史"
      :visible.sync="historyDrawerVisible"
      size="50%"
      class="data-executor-vue-out"
    >
      <div style="padding: 10px">
        <el-tabs value="favorite">
          <el-tab-pane label="我的便签" name="favorite">
            <el-table
              :data="
                myFavoriteList.slice(
                  (labelPage - 1) * labelPageSize,
                  labelPage * labelPageSize
                )
              "
              stripe
              border
              style="width: 100%; margin-bottom: 5px"
              v-infinite-scroll
            >
              <el-table-column
                prop="createUserName"
                label="便签名 "
                :show-overflow-tooltip="true"
              >
                <template slot-scope="scope">
                  <pre style="margin: 0">{{ scope.row.alias }}</pre>
                </template>
              </el-table-column>
              <el-table-column
                prop="content"
                label="SQL"
                :show-overflow-tooltip="true"
              >
                <template slot-scope="scope">
                  <pre style="margin: 0">{{ wrapText(scope.row.content) }}</pre>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="160px">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    v-on:click="
                      inputFavoriteSql(scope.row.content, scope.row.alias)
                    "
                    >输入</el-button
                  >
                  <el-button
                    size="mini"
                    type="danger"
                    v-on:click="delFavorite(scope.row)"
                    style="margin-left: 10px"
                    >删除</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <el-pagination
              style="float: left; margin-top: 30px"
              @size-change="handleLabelSizeChange"
              @current-change="handleLabelCurrentChange"
              :current-page="labelPage"
              :page-sizes="[5, 10, 20, 40]"
              :page-size="labelPageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="myFavoriteList.length"
            >
            </el-pagination>
          </el-tab-pane>
          <el-tab-pane label="历史记录" name="history">
            <el-table
              stripe
              :data="
                myHistoryListList.slice(
                  (historyPage - 1) * historyPageSize,
                  historyPage * historyPageSize
                )
              "
              border
              style="width: 100%; margin-bottom: 5px"
            >
              <el-table-column
                prop="content"
                label="SQL"
                :show-overflow-tooltip="true"
              >
                <template slot-scope="scope">
                  <pre style="margin: 0">{{ wrapText(scope.row.content) }}</pre>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="160px">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    v-on:click="
                      inputFavoriteSql(scope.row.content, scope.row.alias)
                    "
                    >输入</el-button
                  >
                  <el-button
                    size="mini"
                    type="success"
                    v-on:click="insertFavoriteFromHistory(scope.row.content)"
                    style="margin-left: 10px"
                    >收藏</el-button
                  >
                </template>
              </el-table-column>
            </el-table>
            <el-pagination
              style="float: left; margin-top: 30px"
              @size-change="handleHistorySizeChange"
              @current-change="handleHistoryCurrentChange"
              :current-page="historyPage"
              :page-sizes="[5, 10, 20, 40]"
              :page-size="historyPageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="myHistoryListList.length"
            >
            </el-pagination>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-drawer>

    <div v-if="showTable">
      <div style="padding: 0 10px">
        <el-card>
          <div v-if="!!executeError" style="color: white">
            {{ executeError }}
          </div>
          <div
            v-else-if="executeResultList.length <= 0"
            v-loading="sqlExecuting"
          >
            <!--            暂无数据-->
          </div>
          <div id="app" v-else>
            <el-tabs :value="executeShowTable" @tab-click="handleClick">
              <el-tab-pane label="信息" name="table0">
                <div
                  :label="resultItem.index"
                  :key="resultItem.index"
                  :name="'table' + resultItem.index"
                  v-for="resultItem in executeResultInfo"
                >
                  <pre>{{ resultItem }}</pre>
                </div>
              </el-tab-pane>
              <el-tab-pane
                :label="'结果' + resultItem.index"
                :key="resultItem.index"
                :name="'table' + resultItem.index"
                v-for="resultItem in executeResultList"
              >
                <div v-if="!!resultItem.errMsg" style="color: #f00">
                  {{ resultItem.errMsg }}
                </div>
                <div v-else>
                  <el-table
                    id="table-data"
                    ref="multipleTable"
                    :data="
                      resultItem.dataList.slice(
                        (currentPage - 1) * pagesize,
                        currentPage * pagesize
                      )
                    "
                    :header-cell-style="{
                      background: 'rgb(241, 241, 241)',
                      color: 'black',
                      height: '35px',
                      padding: '2px',
                    }"
                    :stripe="true"
                    @select-all="handleAllSelectionChange"
                    @sort-change="tableSortChange"
                    :default-sort="tableSort"
                    :fit="true"
                    row-key="_index"
                    :highlight-current-row="true"
                    style="width: 100%; margin-bottom: 5px"
                    class="execute-result-table"
                    max-height="600"
                  >
                    <el-table-column
                      :reserve-selection="true"
                      type="selection"
                    ></el-table-column>
                    <el-table-column
                      align="center"
                      :show-overflow-tooltip="true"
                      v-for="item in resultItem.dataCols"
                      :prop="item.prop"
                      :key="item.prop"
                      :label="item.prop"
                      :width="200"
                    >
                    </el-table-column>
                  </el-table>
                </div>
                <el-pagination
                  style="float: left; margin-top: 30px"
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
                  :current-page="currentPage"
                  :page-sizes="[5, 10, 20, 40]"
                  :page-size="pagesize"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="resultItem.dataList.length"
                >
                </el-pagination>
                <div
                  style="float: right; margin-top: 30px"
                  v-if="resultItem.dataList.length == 0"
                >
                  显示0条记录
                </div>
                <div style="float: right; margin-top: 30px" v-else>
                  显示从{{ 1 + currentPage * pagesize - pagesize }}到{{
                    currentPage !==
                    (resultItem.dataList.length -
                      (resultItem.dataList.length % pagesize)) /
                      pagesize +
                      1
                      ? 1 + currentPage * pagesize - 1
                      : resultItem.dataList.length
                  }}&emsp; 共{{
                    currentPage !==
                    (resultItem.dataList.length -
                      (resultItem.dataList.length % pagesize)) /
                      pagesize +
                      1
                      ? 1 + currentPage * pagesize - 1
                      : resultItem.dataList.length -
                        (currentPage * pagesize - pagesize)
                  }}条记录
                </div>
              </el-tab-pane>
            </el-tabs>
          </div>
        </el-card>
      </div>
      <span
        id="widthCalculate"
        style="white-space: nowrap; position: fixed"
      ></span>
    </div>
  </div>
</template>

<script>
import sqlFormatter from "sql-formatter";
import datasourceApi from "../../common/api/datasource";
import fileSaver from "file-saver";
import xlsx from "xlsx";
import Editor from "../sqlExcutor/Editor";
export default {
  name: "PageTableView",
  components: { Editor },
  props: ["DatasourceId"],
  data() {
    return {
      paneShow: true,
      pageList: [],
      choiceDatasourceId: "",
      linkList: [],
      activePage: "",
      datasourceList: [],
      datasourceOptions: [],
      datasourceGroupList: [],
      choiceDatasourceGroup: "",
      currentPage: 1, //初始页
      pagesize: 10, //    每页的数据
      historyPage: 1,
      historyPageSize: 10,
      labelPage: 1,
      columnList: [],
      pressDot: false,
      labelPageSize: 10,
      userList: [],
      paneClickDisable: false,
      databaseList: [],
      choiceDatabase: "",
      showTable: true,
      editorDbInfo: [],
      editorDbTableInfo: {},
      editorColumnInfo: {},
      tableSort: {},
      dropdown: 15,
      executeSql: [],
      resultClick: {},
      sqlExecuting: false,
      font_size: this.$store.getters["global/getFont"],
      executeResultList: [],
      executeResultInfo: [],
      executeShowTable: "table1",
      sqlExecutorEditor: {},
      nowExecutorId: 1,
      resultIndex: -1,
      executeError: "",
      // 收藏及历史
      historyDrawerVisible: false,
      myFavoriteList: [],
      myHistoryListList: [],
      tableAliasMap: {},
    };
  },
  mounted: function() {
    this.choiceDatasourceId = this.DatasourceId;
    this.loadDatasourceList();
    // 下面两行先后顺序不能改
    this.addEditorCompleter();
    if (this.choiceDatasourceId) {
      this.loadEditorData(this.choiceDatasourceId);
    }
    this.loadFavoriteList();
  },
  computed: {
    pageTabNameMap() {
      return this.$store.state.global.pageTabNameMap;
    },
  },
  created() {
    console.info(this.$route);
    this.pageList.push(this.$route);
    this.linkList.push(this.$route.fullPath);
    this.activePage = this.$route.fullPath;
  },
  watch: {
    pageList: {
      deep: true,
      handler: function(val) {
        console.log("pagelist ---- ", val);
      },
    },
    $route: function(newRoute, oldRoute) {
      // 如果当前路由不是执行器，那么就显示结果表
      if (this.$route.path === "/data/executor") {
        this.showTable = true;
        this.paneClickDisable = false;
      } else {
        this.showTable = false;
        this.paneClickDisable = true;
      }
      this.activePage = newRoute.fullPath;
      if (this.linkList.indexOf(newRoute.fullPath) < 0) {
        this.linkList.push(newRoute.fullPath);
        this.pageList.push(newRoute);
      }
    },
    font_size: function(val) {
      this.$store.commit("global/setFont", val);
      if (this.$route.path === "/data/executor") {
        this.initAceEditor("sqlExecutorEditor", 30);
        this.sqlExecutorEditor.setFontSize(
          parseInt(this.$store.getters["global/getFont"])
        );
      }
    },
    choiceDatasourceId: function(val) {
      this.choiceDatasourceId = val;
    },
    activePage: function(key) {
      this.$router.push(key).catch((err) => {
        err;
      });
    },
  },
  methods: {
    setcongig(config) {
      this.choiceDatasourceId = config;
    },
    changePane() {
      console.log(document.getElementsByClassName("new-parnet"));
      if (this.paneShow) {
        this.paneShow = false;
        for (
          let i = 0;
          i < document.getElementsByClassName("new-parnet").length;
          i++
        ) {
          document.getElementsByClassName("new-parnet")[i].style.display =
            "none";
        }
      } else {
        this.paneShow = true;
        for (
          let i = 0;
          i < document.getElementsByClassName("new-parnet").length;
          i++
        ) {
          document.getElementsByClassName("new-parnet")[i].style.display =
            "block";
        }
      }
    },
    handleLabelSizeChange: function(size) {
      this.labelPageSize = size;
    },
    handleLabelCurrentChange: function(currentPage) {
      this.labelPage = currentPage;
    },
    handleHistorySizeChange: function(size) {
      this.historyPageSize = size;
    },
    handleHistoryCurrentChange: function(currentPage) {
      this.historyPage = currentPage;
    },
    toggleSelection(rows) {
      if (rows) {
        this.$nextTick(() => {
          rows.forEach((row) => {
            this.$refs.multipleTable[this.resultIndex].toggleRowSelection(
              row,
              true
            );
          });
        });
      } else {
        this.$refs.multipleTable[this.resultIndex].clearSelection();
      }
    },
    handleAllSelectionChange(val) {
      if (this.resultClick[this.resultIndex]) {
        this.$refs.multipleTable[this.resultIndex].clearSelection();
        this.resultClick[this.resultIndex] = false;
        return;
      }
      this.$nextTick(() => {
        this.toggleSelection(this.executeResultList[this.resultIndex].dataList);
        this.resultClick[this.resultIndex] = true;
      });
    },
    handleClick(tab, event) {
      this.resultIndex = parseInt(tab.index) - 1;
      console.log(this.resultIndex);
    },
    get_excel(data) {
      let xlsxParam = { raw: true };
      let box = xlsx.utils.json_to_sheet(data, xlsxParam);
      const workBook = xlsx.utils.book_new();
      xlsx.utils.book_append_sheet(workBook, box);
      return xlsx.write(workBook, {
        bookType: "xlsx",
        bookSST: true,
        type: "array",
      });
    },
    get_csv(data) {
      let xlsxParam = { raw: true };
      let box = xlsx.utils.json_to_sheet(data, xlsxParam);
      return xlsx.utils.sheet_to_csv(box);
    },
    openDownloadDialog(url, saveName) {
      if (typeof url == "object" && url instanceof Blob) {
        url = URL.createObjectURL(url); // 创建blob地址
      }
      var aLink = document.createElement("a");
      aLink.href = url;
      aLink.download = saveName || ""; // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
      var event;
      if (window.MouseEvent) event = new MouseEvent("click");
      else {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(
          "click",
          true,
          false,
          window,
          0,
          0,
          0,
          0,
          0,
          false,
          false,
          false,
          false,
          0,
          null
        );
      }
      aLink.dispatchEvent(event);
    },
    handleCommand(command) {
      if (this.executeSql.length <= 0 || this.resultIndex < 0) {
        this.$message({
          type: "warning",
          message: "当前不存在执行结果",
        });
        return;
      }
      if (command === "all-excel") {
        datasourceApi
          .exportExecute({
            executeId: Date.parse(new Date()),
            sql: this.executeSql[this.resultIndex],
            exportType: 2,
            sourceId: this.choiceDatasourceId,
          })
          .then((response) => {
            this.openDownloadDialog(response, "data.csv");
          })
          .catch((e) => {
            this.$message({
              type: "error",
              message: e,
            });
          });
      } else if (command === "all-csv") {
        datasourceApi
          .exportExecute({
            executeId: Date.parse(new Date()),
            sql: this.executeSql[this.resultIndex],
            exportType: 1,
            sourceId: this.choiceDatasourceId,
          })
          .then((response) => {
            this.openDownloadDialog(response, "data.xls");
          })
          .catch((e) => {
            this.$message({
              type: "error",
              message: e,
            });
          });
      }
      if (this.$refs.multipleTable[this.resultIndex].selection.length == 0) {
        this.$message({
          type: "warning",
          message: "当前不存在选中内容，无法导出!",
        });
        return;
      }
      let copy_selection = Object.assign(
        this.$refs.multipleTable[this.resultIndex].selection
      );
      copy_selection.map(function(item, index) {
        delete copy_selection[index]._index;
      });
      if (command === "select-excel") {
        this.openDownloadDialog(
          new Blob([this.get_excel(copy_selection)]),
          "data.xls"
        );
      } else {
        this.openDownloadDialog(
          new Blob([this.get_csv(copy_selection)]),
          "data.csv"
        );
      }
    },
    tableHeaderColor({ row, column, rowIndex, columnIndex }) {
      if (rowIndex === 0) {
        return "background-color: #F1F1F1;color: #333333;font-weight: bold;";
      }
    },
    handleSizeChange: function(size) {
      this.pagesize = size;
    },
    handleCurrentChange: function(currentPage) {
      this.currentPage = currentPage;
    },
    initAceEditor(editor, minLines) {
      let my_editor = ace.edit(this.$el.querySelector("." + editor), {
        theme: "ace/theme/monokai",
        mode: "ace/mode/sql",
        wrap: "off",
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        showPrintMargin: false,
        minLines: minLines,
        maxLines: 20,
      });
      my_editor.commands.on("afterExec", function(e) {
        if (e.command.name == "insertstring" && /^[\w.]$/.test(e.args)) {
          my_editor.execCommand("startAutocomplete");
        }
      });
      return my_editor;
    },
    cancelExecutorSql() {
      this.sqlExecuting = false;
      this.executeResultList = [];
    },
    loadHistoryAndFavoriteList() {
      this.historyDrawerVisible = true;
      this.loadHistoryList();
      this.loadFavoriteList();
    },
    insertFavoriteFromHistory(content) {
      this.$prompt("请输入名称", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
        inputErrorMessage: "请输入非空的名称",
      })
        .then(({ value }) => {
          let param = {
            name: "我的收藏",
            alias: value,
            content: content,
            datasourceId: this.choiceDatasourceId,
          };
          datasourceApi.updateFavorite(param).then(() => {
            this.$message.success("收藏成功");
            this.loadFavoriteList();
          });
        })
        .catch((e) => {
          console.log(e);
          this.$message({
            type: "info",
            message: "取消输入",
          });
        });
    },
    insertFavoriteList(elem) {
      let sqlValue = this.sqlExecutorEditor.getSelectedText();
      if (!sqlValue) {
        sqlValue = this.sqlExecutorEditor.getValue();
      }
      let param = {
        name: "我的收藏",
        alias: elem,
        content: sqlValue,
        datasourceId: this.choiceDatasourceId,
      };
      datasourceApi.updateFavorite(param).then(() => {
        this.$message.success("收藏成功");
        this.loadFavoriteList();
      });
    },
    loadFavoriteList() {
      datasourceApi
        .favoriteList({ sourceId: this.choiceDatasourceId })
        .then((json) => {
          this.myFavoriteList = json.data || [];
        });
    },
    loadHistoryList() {
      datasourceApi
        .historyList({ sourceId: this.choiceDatasourceId })
        .then((json) => {
          this.myHistoryListList = json.data || [];
        });
    },
    addFavorite(sqlValue) {},
    delFavorite(row) {
      datasourceApi.updateFavorite({ id: row.id, yn: 0 }).then(() => {
        this.$message.success("删除成功");
        this.loadFavoriteList();
      });
    },
    inputFavoriteSql(content, name) {
      if (!name) {
        const length =
          this.pageList.filter(
            (route) => route.query.type === "tmp" && route.query.timestamp
          ).length + 1;
        name = "Untitled-" + length;
      }
      let that = this;
      this.$router
        .push({
          path: "/data/executor",
          query: {
            name: name,
            type: "tag",
            timestamp: new Date().getTime() + Math.ceil(Math.random() * 1000),
          },
        })
        .then(() => {
          this.sqlExecutorEditor = this.initAceEditor("sqlExecutorEditor", 30);
          this.sqlExecutorEditor.setFontSize(
            this.$store.getters["global/getFont"]
          );
          this.sqlExecutorEditor.setValue(content, 1);
          this.sqlExecutorEditor.commands.addCommand({
            name: "execute-sql",
            bindKey: {
              win: "Ctrl-R|Ctrl-Shift-R|Ctrl-Enter",
              mac: "Command-R|Command-Shift-R|Command-Enter",
            },
            exec: function(editor) {
              that.doExecutorSql();
            },
          });
          this.historyDrawerVisible = false;
        })
        .catch((err) => {
          err;
        });
    },
    formatterSql() {
      this.sqlExecutorEditor = this.initAceEditor("sqlExecutorEditor", 30);
      let dataSql = this.sqlExecutorEditor.getSelectedText();
      if (!!dataSql) {
        let range = this.sqlExecutorEditor.getSelectionRange();
        this.sqlExecutorEditor.remove(range);
      } else {
        dataSql = this.sqlExecutorEditor.getValue();
        this.sqlExecutorEditor.setValue("", 1);
      }
      if (!!dataSql) {
        datasourceApi.format({ sql: dataSql }).then((json) => {
          if (json.errCode == 200) {
            this.sqlExecutorEditor.insert(json.data.formatsql);
          } else {
            dataSql = sqlFormatter.format(dataSql);
            this.sqlExecutorEditor.insert(dataSql);
          }
        });
      }
    },
    doExecutorSql() {
      if (!this.choiceDatasourceId) {
        this.$message.error("请先选择数据源");
        return;
      }
      if (
        this.$route.query.sourceId &&
        "" + this.choiceDatasourceId !== this.$route.query.sourceId
      ) {
        this.$message.warning("该编辑器所属数据源未激活");
        return;
      }
      this.executeError = "";
      this.executeUseTime = "";
      this.executeResultList = [];

      this.nowExecutorId =
        new Date().getTime() + Math.ceil(Math.random() * 1000);
      this.sqlExecutorEditor = this.initAceEditor("sqlExecutorEditor", 30);
      var sqlValue = this.sqlExecutorEditor.getSelectedText();
      if (!sqlValue) {
        sqlValue = this.sqlExecutorEditor.getValue();
      }
      var reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(-{2,}.*?(\r|\n))|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)/g;
      sqlValue = sqlValue.replace(reg, function(word) {
        // 去除注释后的文本
        return /^\/{2,}/.test(word) || /^\/\*/.test(word) ? "" : word;
      });
      this.sqlExecuting = true;
      datasourceApi
        .queryExecuteSql({
          sourceId: this.choiceDatasourceId,
          executeId: this.nowExecutorId,
          sql: sqlValue,
          params: "",
        })
        .then((json) => {
          this.sqlExecuting = false;
          if (json.errCode != 200) {
            this.executeError = json.errMsg;
            return;
          }
          var resultList = json.data || [];
          var executeResultList = [];
          var executeResultInfo = [],
            itemIndex = 1;
          this.showTable = true;
          for (var i = 0; i < resultList.length; i++) {
            var objItem = JSON.parse(resultList[i]);
            executeResultInfo.push(this.getExecuteInfoStr(objItem));
            this.executeSql.push(objItem.sql);
            var resultItem = this.dealExecuteResult(objItem);
            if (resultItem.updateCount < 0) {
              resultItem.index = itemIndex;
              itemIndex++;
            }
            executeResultList.push(resultItem);
          }
          this.resultIndex = 0;
          this.executeShowTable = itemIndex === 1 ? "table0" : "table1";
          this.executeResultInfo = executeResultInfo;
          this.executeResultList = executeResultList;
        });
    },
    dealExecuteResult(resultData) {
      var dataList = resultData.result || [];
      var executeResultCols = [];
      if (dataList.length > 0) {
        var propData = dataList[0];
        for (var key in propData) {
          // 动态计算宽度~自己想的一个方法，666
          console.info(document.getElementById("widthCalculate"));
          document.getElementById("widthCalculate").innerText = key;
          var width1 = document.getElementById("widthCalculate").offsetWidth;
          document.getElementById("widthCalculate").innerText = propData[key];
          var width2 = document.getElementById("widthCalculate").offsetWidth;
          var width = width1 > width2 ? width1 : width2;
          width = width < 50 ? 50 : width;
          width = width > 200 ? 200 : width;
          executeResultCols.push({ prop: key, width: width + 25 });
        }
        for (var i = 0; i < dataList.length; i++) {
          dataList[i]._index = i + 1;
        }
      }
      var resultObj = {};
      resultObj.dataList = dataList;
      resultObj.dataCols = executeResultCols;
      resultObj.useTime = resultData.useTime || 0;
      resultObj.errMsg = resultData.errMsg || "";
      document.getElementById("widthCalculate").innerText = "";
      resultObj.updateCount = resultData.updateCount;
      return resultObj;
    },
    getExecuteInfoStr(resultData) {
      let resultStr = resultData.sql;
      resultStr += "  状态：" + (!!resultData.errMsg ? "ERROR" : "OK");
      if (resultData.updateCount >= 0) {
        resultStr += "\n影响行数：" + resultData.updateCount;
      }
      resultStr += "\n耗时：" + (resultData.useTime || 0) / 1000 + "s";
      resultStr += "\n\n";
      return resultStr;
    },
    tableSortChange(sort) {
      if (
        this.tableSort.prop === sort.prop &&
        this.tableSort.order === sort.order
      )
        return;
      this.tableSort = { prop: sort.prop, order: sort.order };
      this.doExecutorSql();
    },
    getExecuteSql() {
      if (this.$route.query.dbType == "com.mysql.jdbc.Driver") {
        return (
          "select * from " +
          "`" +
          this.$route.query.dbName +
          "`" +
          "." +
          "`" +
          this.$route.query.tableName +
          "`" +
          " limit " +
          this.pagesize +
          " offset " +
          (this.currentPage - 1) * this.pagesize +
          ";"
        );
      } else if (this.$route.query.dbType == "org.postgresql.Driver") {
        return (
          "select * from " +
          this.$route.query.dbName +
          "." +
          this.$route.query.tableName +
          " limit " +
          this.pagesize +
          " offset " +
          (this.currentPage - 1) * this.pagesize +
          ";"
        );
      } else if (
        this.$route.query.dbType == "net.sourceforge.jtds.jdbc.Driver"
      ) {
        return (
          "select top " +
          this.pagesize +
          " * from " +
          this.$route.query.dbName +
          "." +
          this.$route.query.tableName
        );
      }

      return (
        "select * from " +
        this.$route.query.dbName +
        "." +
        this.$route.query.tableName +
        " limit " +
        this.pagesize +
        " offset " +
        (this.currentPage - 1) * this.pagesize +
        ";"
      );
    },
    loadEditorData(choiceDatasourceId) {
      datasourceApi
        .getEditorData({ sourceId: choiceDatasourceId })
        .then((json) => {
          let data = json.data || {};
          this.editorDbInfo = data.db || [];
          this.editorDbTableInfo = data.table || {};
          this.editorColumnInfo = data.column || {};
        });
    },
    async addEditorCompleter() {
      let that = this;
      var languageTools = ace.require("ace/ext/language_tools");
      languageTools.addCompleter({
        needDestory: true, // 一定得加上这个参数~不然页面生命周期内页面的切换，编辑器会有多个相同的completer
        getCompletions: function(editor, session, pos, prefix, callback) {
          var isFound = false;
          var callbackArr = [];
          var lineStr = session.getLine(pos.row).substring(0, pos.column - 1);
          var currentStr = session.getLine(pos.row).substring(0, pos.column);
          var pressStr = session
            .getLine(pos.row)
            .substring(pos.column - 1, pos.column);
          if (lineStr.endsWith("from ") || lineStr.endsWith("join ")) {
            // 库
            for (var i = 0; i < that.editorDbInfo.length; i++) {
              callbackArr.push({
                caption: that.editorDbInfo[i].dbName,
                snippet: that.editorDbInfo[i].dbName,
                meta: "database",
                type: "snippet",
                score: 1000,
              });
            }
            // 所有表
            for (var key in that.editorDbTableInfo) {
              var tableInfo = that.editorDbTableInfo[key];
              for (var i = 0; i < tableInfo.length; i++) {
                var caption = !!tableInfo[i].tableComment
                  ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                  : tableInfo[i].tableName;
                callbackArr.push({
                  caption: caption,
                  snippet: tableInfo[i].tableName,
                  meta: "table",
                  type: "snippet",
                  score: 1000,
                });
              }
            }
            callback(null, callbackArr);
          } else if (currentStr.endsWith(".")) {
            // 获取当前用户输入的SQL
            var sqlValue = "";
            // 往前加
            for (var i = pos.row; i >= 0; i--) {
              var tempLine = session.getLine(i);
              sqlValue = tempLine + " " + sqlValue;
              if (tempLine.indexOf(";") >= 0) {
                break;
              }
            }
            // 往后加
            for (var i = pos.row + 1; i < session.getLength(); i++) {
              var tempLine = session.getLine(i);
              sqlValue = sqlValue + " " + tempLine;
              if (tempLine.indexOf(";") >= 0) {
                break;
              }
            }
            var reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(-{2,}.*?(\r|\n))|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)/g;

            sqlValue = sqlValue.replace(reg, function(word) {
              // 去除注释后的文本
              return /^\/{2,}/.test(word) || /^\/\*/.test(word) ? "" : word;
            });

            // 由于后端无法解析别名+.，所以要把当前输入的sql中的.去掉
            sqlValue = sqlValue.replace(". ", " ");
            let response = datasourceApi
              .tableAlias({
                sql: sqlValue,
                driverType: "com.mysql.jdbc.Driver",
              })
              .then((response) => {
                let splitStr = currentStr.split(",");
                splitStr = splitStr[splitStr.length - 1];
                splitStr = splitStr.split(" ");
                splitStr = splitStr[splitStr.length - 1];
                let aliasName = splitStr
                  .substring(0, splitStr.length - 1)
                  .trim();
                // 如果别名匹配到了真实表分两种情况
                // 1、这个是别名.
                // 2、这个是from 后面数据库后面按.
                if (response.data && response.data[aliasName]) {
                  let splitStr = response.data[aliasName].split(".");
                  var aa =splitStr.length
                  if (splitStr.length > 1) {
                    let dbName = splitStr[0].trim();
                    let tableName = splitStr[1].trim();
                    // mysql和postgresql的查询不一样
                    let editorColumnInfo;
                    if (
                      that.$parent.$parent.$parent.$parent.dbType ===
                      "com.mysql.jdbc.Driver"
                    ) {
                      editorColumnInfo = that.editorColumnInfo[tableName];
                    } else {
                      editorColumnInfo = that.editorColumnInfo[dbName];
                    }

                    for (var i = 0; i < editorColumnInfo.length; i++) {
                      if (editorColumnInfo[i].tableName !== tableName) {
                        continue;
                      }
                      callbackArr.push({
                        caption: editorColumnInfo[i].name,
                        snippet: editorColumnInfo[i].name,
                        meta: "column",
                        type: "snippet",
                        score: 1000,
                      });
                    }
                  } else {
                    let tableName = splitStr[0].trim();
                    let editorColumnInfo = that.editorColumnInfo[tableName];
                    for (var i = 0; i < editorColumnInfo.length; i++) {
                      callbackArr.push({
                        caption: editorColumnInfo[i].name,
                        snippet: editorColumnInfo[i].name,
                        meta: "column",
                        type: "snippet",
                        score: 1000,
                      });
                    }
                  }
                } // 处理数据库按点的情况
                else {
                  // 所有表
               try {
                 if (aliasName.indexOf(".") > 0) {
                   var ttt = aliasName.split(".")
                   ttt.length
                   aliasName = ttt[ttt.length - 1]
                 }
                 if (that.editorDbTableInfo[aliasName]) {
                 var tableInfo = that.editorDbTableInfo[aliasName];
                 for (var i = 0; i < tableInfo.length; i++) {
                   var caption = !!tableInfo[i].tableComment
                           ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                           : tableInfo[i].tableName;
                   callbackArr.push({
                     caption: caption,
                     snippet: tableInfo[i].tableName,
                     meta: "table",
                     type: "snippet",
                     score: 1000,
                   });
                 }
               }
                 if( that.editorColumnInfo[aliasName]){
                   let editorColumnInfo = that.editorColumnInfo[aliasName];
                   for (var i = 0; i < editorColumnInfo.length; i++) {
                     callbackArr.push({
                       caption: editorColumnInfo[i].name,
                       snippet: editorColumnInfo[i].name,
                       meta: "column",
                       type: "snippet",
                       score: 1000,
                     });
                   }
                 }
               }catch (e) {
                 console.info("error")
               }
                }
                callbackArr.push({
                  caption: "",
                  snippet: "",
                  meta: "table",
                  type: "null",
                  score: 1000,
                });
                callback(null, callbackArr);
                that.pressDot = true;
                that.columnList = callbackArr;
                return;
              });
          } else if (
            lineStr.endsWith("select ") ||
            lineStr.endsWith("where ") ||
            lineStr.endsWith("and ")
          ) {
            var queryText = "";
            // 往前加
            for (var i = pos.row; i >= 0; i--) {
              var tempLine = session.getLine(i);
              queryText = tempLine + " " + queryText;
              if (tempLine.indexOf(";") >= 0) {
                break;
              }
            }
            // 往后加
            for (var i = pos.row + 1; i < session.getLength(); i++) {
              var tempLine = session.getLine(i);
              queryText = queryText + " " + tempLine;
              if (tempLine.indexOf(";") >= 0) {
                break;
              }
            }
            // 所有表，找下面的字段列表
            for (var key in that.editorDbTableInfo) {
              var tableInfo = that.editorDbTableInfo[key];
              for (var i = 0; i < tableInfo.length; i++) {
                if (queryText.indexOf(tableInfo[i].tableName) < 0) {
                  continue;
                }
                var columnInfo;
                if (
                  that.$parent.$parent.$parent.$parent.dbType ===
                  "com.mysql.jdbc.Driver"
                ) {
                  columnInfo = that.editorColumnInfo[tableInfo[i].tableName];
                  if (!!columnInfo) {
                    for (var j = 0; j < columnInfo.length; j++) {
                      var caption = !!columnInfo[j].description
                        ? columnInfo[j].name + "-" + columnInfo[j].description
                        : columnInfo[j].name;
                      callbackArr.push({
                        caption: caption,
                        snippet: columnInfo[j].name,
                        meta: "column",
                        type: "snippet",
                        score: 1000,
                      });
                    }
                    isFound = true;
                  }
                } else {
                  columnInfo = that.editorColumnInfo[key];
                  if (!!columnInfo) {
                    for (var j = 0; j < columnInfo.length; j++) {
                      if (columnInfo[j].tableName !== tableInfo[i].tableName) {
                        continue;
                      }
                      var caption = !!columnInfo[j].description
                        ? columnInfo[j].name + "-" + columnInfo[j].description
                        : columnInfo[j].name;
                      callbackArr.push({
                        caption: caption,
                        snippet: columnInfo[j].name,
                        meta: "column",
                        type: "snippet",
                        score: 1000,
                      });
                    }
                    isFound = true;
                  }
                }
              }
            }
            callback(null, callbackArr);
          } else {
            if (that.pressDot && pressStr != "") {
              callback(null, that.columnList);
              return;
            }
            that.pressDot = false;
            // 库
            for (var i = 0; i < that.editorDbInfo.length; i++) {
              callbackArr.push({
                caption: that.editorDbInfo[i].dbName,
                snippet: that.editorDbInfo[i].dbName,
                meta: "database",
                type: "snippet",
                score: 1000,
              });
            }
            // 所有表
            for (var key in that.editorDbTableInfo) {
              var tableInfo = that.editorDbTableInfo[key];
              for (var i = 0; i < tableInfo.length; i++) {
                var caption = !!tableInfo[i].tableComment
                  ? tableInfo[i].tableName + "-" + tableInfo[i].tableComment
                  : tableInfo[i].tableName;
                callbackArr.push({
                  caption: caption,
                  snippet: tableInfo[i].tableName,
                  meta: "table",
                  type: "snippet",
                  score: 1000,
                });
                var columnInfo = that.editorColumnInfo[tableInfo[i].tableName];
                if (columnInfo) {
                  for (var j = 0; j < columnInfo.length; j++) {
                    var caption = !!columnInfo[j].description
                      ? columnInfo[j].name + "-" + columnInfo[j].description
                      : columnInfo[j].name;
                    callbackArr.push({
                      caption: caption,
                      snippet: columnInfo[j].name,
                      meta: "column",
                      type: "snippet",
                      score: 1000,
                    });
                  }
                }
              }
            }
            callback(null, callbackArr);
          }
        },
      });
    },
    initLoadDataList(param) {
      this.$emit("initLoadDataList", param);
    },
    getPageListIndex() {
      let index = this.linkList.indexOf(this.$route.fullPath);
      console.log(index);
    },
    loadDatasourceList() {
      this.$emit("loadDatasourceList");
    },
    changePage(key) {
      this.activePage = key.name;
    },

    wrapText(cellValue) {
      var aa = cellValue;
      return cellValue.replace(/(\r\n|\n|\r)/gm, "");
    },
    editPage(key, action) {
      this[action](key);
    },
    removePageTab(key) {
      if (this.pageList.length === 1) {
        this.$message.warning("这是最后一页，不能再关闭了啦");
        return;
      }
      this.pageList = this.pageList.filter((item) => item.fullPath !== key);
      let index = this.linkList.indexOf(key);
      this.linkList = this.linkList.filter((item) => item !== key);
      index = index >= this.linkList.length ? this.linkList.length - 1 : index;
      this.activePage = this.linkList[index];
    },
  },
};
</script>

<style>
.el-color-picker--small .el-color-picker__trigger {
  top: 11px;
  left: 20px;
  height: 32px;
  width: 32px;
}

.editor-export {
  width: 16px;
  margin-left: 2px;
  height: 16px;
  background: url("");
  background-size: 100%;
  display: block;
}

.editor-excel {
  width: 16px;
  margin-left: 2px;
  height: 16px;
  background: url("");
  background-size: 100%;
  display: block;
}

.editor-csv {
  width: 16px;
  margin-left: 2px;
  height: 16px;
  background: url("");
  background-size: 100%;
  display: block;
}

.editor-text {
  width: 16px;
  margin-left: 2px;
  height: 16px;
  background: url("");
  background-size: 100%;
  display: block;
}

.data-executor-vue-out {
}
.el-drawer__header span:focus {
  outline: 0;
}
.el-drawer__header {
  margin-bottom: 0px;
}
.el-tabs__header {
  margin: 0 0 0 0;
}
.el-drawer__body {
  overflow-y: auto;
}

.el-table .cell {
  white-space: pre-line;
}
</style>
